import React, { useEffect, useState, useCallback } from 'react';
import { initView } from 'dingtalk-docs-cool-app';
import { Typography, Button, Collapse, Card, Tabs, Spin, Alert, Input, Form, Select,Toast } from 'dingtalk-design-desktop';

 
import FormItem from 'dingtalk-design-desktop/lib/form/FormItem';
import { getLocale, } from './locales';
import './style.css';
import { markTypeOptions, getFieldValue, isEmptyStr,isEmptyArr,Default_duplicateFieldName } from '../utils';
import FinanceList from './FinanceList';
import  { useRecord } from '../hooks/record';

function App() {
  // 获取构建时间戳作为版本号
const BUILD_TIMESTAMP = process.env.BUILD_TIMESTAMP ||'1.0.0';
  const [locale, setLocale] = useState<Locales>(getLocale('zh-CN'));
  const [loading, setLoading] = useState<boolean>(false);
  const [documentInfo, setDocumentInfo] = useState<DocumentInfo | null>(null);
  const [sheets, setSheets] = useState<Sheet[]>([]);
  const [activeSheet, setActiveSheet] = useState<Sheet | null>(null);
  const [fields, setFields] = useState<Field[]>([]);
  // const [records, setRecords] = useState<DocRecord[]>([]);
  const {records,setRecords, loadAllRecords} = useRecord();

  // 存储事件监听器的取消函数
  const [eventUnsubscribers, setEventUnsubscribers] = useState<Array<() => void>>([]);

 

  useEffect(() => {
    const initialize = async () => {
      setLoading(true);
      try {
        await Promise.all([
          loadDocumentInfo(),
          loadSheets(),
          loadActiveSheet(),
          loadFields()
        ]);
      } catch (error: any) {
        console.error(`${locale.operationFailed}: ${error.message}`);
      } finally {
        setLoading(false);
      }
    };

    let unsubscribers: Array<() => void> = [];
    let lastSheetId: string | null = null; // 记录上次的sheetId，避免重复触发
    let debounceTimer: NodeJS.Timeout | null = null; // 防抖定时器

    const setupEvents = () => {
      try {
        // 监听选择变化（包括activeSheet变化）
        const offSelectionChanged = Dingdocs.base.event.onSelectionChanged((selection) => {
          // 只有当sheetId真正变化时才更新状态
          if (selection.sheetId && selection.sheetId !== lastSheetId) {
            lastSheetId = selection.sheetId;
            console.log('Active sheet changed to:', selection.sheetId);

            // 使用防抖来避免频繁调用
            if (debounceTimer) {
              clearTimeout(debounceTimer);
            }
            debounceTimer = setTimeout(() => {
              loadActiveSheet();
              loadDocumentInfo(); // 更新文档信息，包括当前表名
            }, 300); // 300ms防抖延迟
          }
        });
        unsubscribers.push(offSelectionChanged);

        // 监听数据表添加事件
        const offSheetInserted = Dingdocs.base.event.onSheetInserted((event) => {
          console.log('Sheet inserted:', event);
          loadSheets();
          loadDocumentInfo();
        });
        unsubscribers.push(offSheetInserted);

        // 监听数据表删除事件
        const offSheetDeleted = Dingdocs.base.event.onSheetDeleted((event) => {
          console.log('Sheet deleted:', event);
          loadSheets();
          loadDocumentInfo();
          // 如果删除的是当前激活的表，重新加载当前表
          loadActiveSheet();

        });
        unsubscribers.push(offSheetDeleted);

        // 监听字段添加事件
        const offFieldInserted = Dingdocs.base.event.onFieldInserted((event) => {
          console.log('Field inserted:', event);
          // 如果是当前表的字段变化，重新加载字段列表
          if (!activeSheet || event.sheetId === activeSheet.id) {
            loadFields();
          }
          loadSheets(); // 更新字段数量
        });
        unsubscribers.push(offFieldInserted);

        // 监听字段修改事件
        const offFieldModified = Dingdocs.base.event.onFieldModified((event) => {
          console.log('Field modified:', event);
          if (!activeSheet || event.sheetId === activeSheet.id) {
            loadFields();
          }
        });
        unsubscribers.push(offFieldModified);

        // 监听字段删除事件
        const offFieldDeleted = Dingdocs.base.event.onFieldDeleted((event) => {
          console.log('Field deleted:', event);
          if (!activeSheet || event.sheetId === activeSheet.id) {
            loadFields();
          }
          loadSheets(); // 更新字段数量
        });
        unsubscribers.push(offFieldDeleted);

        // 监听记录添加事件
        const offRecordInserted = Dingdocs.base.event.onRecordInserted((event) => {
          console.log('Record inserted:', event);
          if (!activeSheet || event.sheetId === activeSheet.id) {
            loadRecords();
          }
        });
        unsubscribers.push(offRecordInserted);

        // 监听记录修改事件
        const offRecordModified = Dingdocs.base.event.onRecordModified((event) => {
          console.log('Record modified:', event);
          if (!activeSheet || event.sheetId === activeSheet.id) {
            loadRecords();
          }
        });
        unsubscribers.push(offRecordModified);

        // 监听记录删除事件
        const offRecordDeleted = Dingdocs.base.event.onRecordDeleted((event) => {
          console.log('Record deleted:', event);
          if (!activeSheet || event.sheetId === activeSheet.id) {
            loadRecords();
          }
        });
        unsubscribers.push(offRecordDeleted);

        // 保存所有取消监听的函数
        setEventUnsubscribers(unsubscribers);

        console.log('Event listeners setup completed');
      } catch (error: any) {
        console.error('Failed to setup event listeners:', error);
      }
    };

    initView({
      onReady: async () => {
        // 获取当前语言设置
        try {
          const currentLocale = await Dingdocs.base.host.getLocale();
          setLocale(getLocale(currentLocale));
        } catch (e) {
          console.warn('Failed to get locale, using default zh-CN');
        }
        // 初始化数据
        await initialize();
        // 设置事件监听
        setupEvents();
      },
    });

    // 清理函数
    return () => {
      if (debounceTimer) {
        clearTimeout(debounceTimer);
      }
      unsubscribers.forEach(unsubscribe => {
        try {
          unsubscribe();
        } catch (error) {
          console.warn('Failed to unsubscribe event listener:', error);
        }
      });
    };
  }, []); // 这里故意只在组件挂载时运行一次

  // 清理事件监听器
  useEffect(() => {
    return () => {
      eventUnsubscribers.forEach(unsubscribe => {
        try {
          unsubscribe();
        } catch (error) {
          console.warn('Failed to unsubscribe event listener:', error);
        }
      });
    };
  }, [eventUnsubscribers]);

  // 加载文档信息
  const loadDocumentInfo = useCallback(async () => {
    try {
      const info = await Dingdocs.script.run('getDocumentInfo');
      setDocumentInfo(info);
    } catch (error: any) {
      console.error('Load document info failed:', error);
    }
  }, []);

  // 加载数据表列表
  const loadSheets = useCallback(async () => {
    try {
      const sheetList = await Dingdocs.script.run('getAllSheets');
      setSheets(sheetList);
    } catch (error: any) {
      console.error('Load sheets failed:', error);
    }
  }, []);

  // 加载字段列表
  const loadFields = useCallback(async (sheetId?: string) => {
    try {
      const fieldList = await Dingdocs.script.run('getSheetFields', sheetId);
      setFields(fieldList);
    } catch (error: any) {
      console.error('Load fields failed:', error);
    }
  }, []);

  // 加载当前激活的数据表
  const loadActiveSheet = useCallback(async () => {
    try {
      const sheet = await Dingdocs.script.run('getActiveSheet');
      setActiveSheet(sheet);
      if (sheet) {
        await loadFields(sheet.id);
      }
    } catch (error: any) {
      console.error('Load active sheet failed:', error);
    }
  }, [loadFields]);

  // 加载记录列表
  const loadRecords = useCallback(async (sheetId?: string) => {
    try {
      const recordData = await Dingdocs.script.run('getRecords', sheetId);
      console.log('Loaded records:', recordData);
      setRecords(recordData.records);
    } catch (error: any) {
      console.error('Load records failed:', error);
    }
  }, []);

   

 
  const [form] = Form.useForm<{ idFieldsInput: string; markType: string; duplicateFieldName: string; }>();
  const [btnLoading, setBtnLoading] = useState<boolean>(false);
  const submitForm = async (values: any) => {
    const { idFieldsInput, markType, duplicateFieldName } = values;
    if (isEmptyStr(idFieldsInput)||isEmptyStr(duplicateFieldName)) {
      alert('请选择');
      return;
    }
    setBtnLoading(true);
    
    
    const allRecords = await loadAllRecords(activeSheet?.id);
    setRecords(allRecords);
    // alert('records length:'+records.length);
    // 确保records状态已更新后再继续执行
    // await new Promise(resolve => setTimeout(resolve, 0));
    
    const idFields= idFieldsInput.map(field => field.trim());
    // const comparisonField = formResult.comparisonField;
    
    // 验证标识字段是否存在
    // const sheetFields = sheet.getFields();
    // const fieldNames = fields.map(field => field.getName());
    // const fieldIds = fields.map(field => field.getId());
    // const validFields = [...fieldNames];
    // const invalidFields = idFields.filter(field => !validFields.includes(field));
    // if (invalidFields.length > 0) {
    //   alert(`以下标识字段不存在: ${invalidFields.join(', ')}`);
    //   return;
    // }

    const duplicateFlagField = await Dingdocs.script.run('addField', duplicateFieldName, 'text');
    const duplicateFlagFieldId = duplicateFlagField.id;

 
    // 用于存储需要更新的记录
    const updates:DocRecord[] = [];
    // 按标识字段分组记录
    const groups:GroupRecords = {};
    for (const [index, record] of Object.entries(allRecords)) {

      const keyArr = idFields.map(field => getFieldValue(record, field))
      if(isEmptyArr(keyArr)){
          continue;// 跳出本次循环['']
      }
      const key = JSON.stringify(keyArr);
      if (!groups[key]) {
        groups[key] = { rowIndexs: [], records: [] };
      }
      groups[key].rowIndexs.push(index+1)
      groups[key].records.push(record);
    }
    
    // 处理每个分组
    for (const [key, groupItem] of Object.entries(groups)) {
      if (groupItem.records.length === 1) {
        // 非重复记录，确保标记字段为空
        updates.push({
          id: groupItem.records[0].id,
          fields: {
            [duplicateFlagFieldId]: ''
          }
        });
      } else {
        // 重复记录，根据标记方式进行标记
        let recordsToMark = [...groupItem.records];
       // let IndexTo[...groupItem.records]
        if (markType === '首项不标记') {
          recordsToMark = recordsToMark.slice(1);
        } else if (markType === '末项不标记') {
          // 按比较字段排序，不标记最后一项
          recordsToMark = recordsToMark.slice(0, -1);
        }
        // 标记需要标记的记录
        for (const record of recordsToMark) {
          updates.push({
            id: record.id,
            fields: {
              [duplicateFlagFieldId]: `第[${groupItem.rowIndexs}] 行重复`
            }
          });
        }
        // 对于未标记的记录，确保标记字段为空
        const unmarkedRecords = groupItem.records.filter(record => !recordsToMark.includes(record));
        for (const record of unmarkedRecords) {
          updates.push({
            id: record.id,
            fields: {
              [duplicateFlagFieldId]: ''
            }
          });
        }
      }
    }
    await Dingdocs.script.run('batchUpdate',  activeSheet?.id, updates)
    // await loadFields();
    // await loadAllRecords(); 
    setTimeout(()=>{
      setBtnLoading(false);
    },1500)
    Toast.success(`操作成功`);
  };

  if (loading) {
    return (
      <div className='page'>
        <div className='loading'>
          <Typography.Text>{locale.loading}</Typography.Text>
        </div>
      </div>
    );
  }

  return (
    <div className="app">
      <div className="header">
        {documentInfo && (
          <div>
            <span style={{ color: '#1890ff', marginLeft: '8px' }}>[{locale.currentTable}]</span>
            <Typography.Text strong>{documentInfo && documentInfo.currentSheet}</Typography.Text>
          </div>
        )}
        <div style={{ position: 'absolute', top: 8, right: 8, fontSize: '12px', color: '#999' }}>
          V{BUILD_TIMESTAMP}
        </div>
      </div>
      <Tabs defaultActiveKey="1">
        <Tabs.TabPane tab="汇率同步" key="1">
          <FinanceList />
        </Tabs.TabPane>
        <Tabs.TabPane tab="标记重复项" key="2"  >
          <div style={{ padding: '0 20px',position:'relative', minHeight:'750px'}}>
            <Form onFinish={submitForm} form={form} layout="vertical"  initialValues={{ duplicateFieldName: Default_duplicateFieldName }} >
              <FormItem label="标识字段" required key="idFieldsInput" name="idFieldsInput">
                <Select mode="multiple"
                  placeholder="请选择"
                  style={{ width: '100%' }}
                >
                  {fields.map((field) => (
                    <Select.Option value={field.name} key={field.id}>{field.name}</Select.Option>
                  ))
                  }
                </Select>
              </FormItem>
              <FormItem label="标识方式" required key="markType" name="markType">
                <Select
                  placeholder="请选择"
                  style={{ width: '100%' }}
                  options={markTypeOptions}
                >
                </Select>
              </FormItem>
              <FormItem label="标记项字段名" required key="duplicateFieldName" name="duplicateFieldName">
                <Input      />
              </FormItem>
              <Form.Item wrapperCol={{ span: 18, offset: 6 }}>
                <Button size="large" type="primary" htmlType="submit" loading={btnLoading}>
                  查找
                </Button>
              </Form.Item>
            </Form>
          </div>
          <div style={{color:'#666',position:'absolute',bottom:'20px',fontSize:'12px',left:'20px'}}>
            1. 标识字段: 支持多选。例如选择[订单号,金额] 会把订单号和金额同时相同的 标记为重复项。
          </div>
        </Tabs.TabPane>
    
      </Tabs>
    </div>
  );
}

export default App;
